/*qAwoZwb4iRZtdrtoX/lUZl5E+x/ew3/ziNJuzypr8/P0d8LwDGSkeUCqGQ4sx8zH*/
/*
 * @Descripttion:
 * @version:
 * @Author: Chendch
 * @Date: 2020-10-10 17:36:07
 * @LastEditors: Chendch
 * @LastEditTime: 2021-04-12 09:05:37
 */
import {isObject, getVariableType} from "./typeRegUtil";
/**
 * @desc 判断两个数组是否相等
 * @param {Array} arr1
 * @param {Array} arr2
 * @return {Boolean}
 */
export const arrayEqual = (arr1, arr2) => {
    if(arr1 === arr2) return true;
    if(arr1.length !== arr2.length) return false;
    for(let i=0; i< arr1.length; i++) {
        if(arr1[i] !== arr2[i]) return false;
    }
    return true;
}

 /** 递归方式将obj的所有树路径规整到二维数组中，第一维度表示路径个数，第二个维度表示每条路径上的节点
* 返回的是这个二维数组
*/
function getObjKeyPath(pathArry, paths, obj){
    for(let key in obj){
        let type = obj[key].constructor.name; //获取属性值对应的类型
        if(type == "Object"){
            if(!paths){
                paths = [];
            }
            paths.push(key);
            getObjKeyPath(pathArry, paths, obj[key]);
        }else{
            if(!paths){
                pathArry.push([key]);
            }else{
                var arry = paths.concat();//目的是复制数组
                arry.push(key);
                pathArry.push(arry);
            }
        }
    }
    return pathArry;
}

/**
 * @desc 判断两个对象是否相等
 * @param {Object} a
 * @param {Object} b
 * @return {Boolean}
 */
export const objectEqual = (obj1, obj2) => {
    let keys1  = getObjKeyPath([], null, obj1),
        keys2  = getObjKeyPath([], null, obj2),
        bigObj   = null,
        smallObj = null,
        keys = null;
    if(keys1.length >= keys2.length){
        bigObj   = obj1;
        smallObj = obj2;
        keys     = keys1;
    }else{
        bigObj   = obj2;
        smallObj = obj1;
        keys     = keys2;
    }
    for(var i in keys){
        var val1 = bigObj;
        var val2 = smallObj;
        for(var j in keys[i]){
            var key = keys[i][j];
            val1 = val1[key];
            val2 = val2[key];
            if(val2 == undefined){
                return false;
            }
        }
        if(val1 != val2){
            return false;
        }
    }
    return true;
}

/**
 * @desc 判断两个基本类型的变量是否完全相同
 * @param {String} param1
 * @param {String} param2
 * @return {Boolean}
 */
export const baseTypeEqual = (param1, param2) => {
   return Object.is(param1, param2);
}

function strMap2Obj(strMap) {
    let obj = Object.create(null);
    for (let [k,v] of strMap) {
      obj[k] = v;
    }
    return obj;
  }
  /**
   * @desc 判断两个值是否相等
   * @param
   * @param
   * @return {Boolean}
   */
export const Equals = (param1, param2) => {
  /**
   * 对象比较函数
   *
   * @param arg1
   * @param arg2
   * @returns {Boolean}
   */
  function equalsObject(arg1, arg2) {

      // 获得 对象的length属性，以判断是数组还是 对象
      let arg1Len = arg1.length,
        arg2Len = arg2.length,
        len1 = 0,
        len2 = 0;
      if (arg1Len && arg2Len) {
          len1 = arg1.length;
          len2 = arg2.length;
      } else if (!arg1Len && !arg2Len) {
          for (let obj in arg1) len1++;
          for (let obj in arg2) len2++;
      } else {
          return false;
      }
      if (len1 !== len2) {
          return false;
      }
      if (arg1Len && arg2Len) {
          for (let i =0; i < arg1Len; i++) {
              if (!inLoop(arg1[i], arg2[i])){
                  return false;
              }
          }
      } else if (!arg1Len && !arg2Len) {
          for (let index in arg1) {
              if (!inLoop(arg1[index], arg2[index])) {
                  return false;
              }
          }
      } else {
          return false;
      }

      return true;
  }

  /**
   * 具体比较方式
   *
   * @param e1
   * @param e2
   * @returns {Boolean}
   */
    function inLoop(e1, e2) {
      if (e1 === e2) {
          return true;
      }

      var t1 = typeof e1;
      var t2 = typeof e2;
      // 数据类型不同
      if (t1 !== t2) {
          return false;
      }
      // 其中一个元素是 null 或 undefiend
      if ((null === e1 && null !== e2) || (null !== e1 && null === e2)) {
          return false;
      }
      if ((undefined === e1 && undefined !== e2)
              || (undefined !== e1 && undefined === e2)) {
          return false;
      }
      // 无法判断函数
      if ('function' === t1 || 'function' === t2) {
          throw new Error("无法比较函数");
      }
      // 递归
      return equalsObject(e1, e2);
  }
  function getType(param) {
      return Object.prototype.toString.call(param).slice(8, -1).toLowerCase();
  }

  let isEqual = false;
  if(getType(param1) !== getType(param2))
      return isEqual;
  switch(getType(param1)) {
      case "undefined":
      case "null":
          isEqual = true;
          break;
      case "string":
      case "number":
          isEqual = param1 === param2;
          break;
      case "array":
      case "object":
          isEqual = equalsObject(param1, param2);
          break;
      case "set":
          isEqual = equalsObject(Array.from(param1), Array.from(param2));
          break;
      case "map":
          isEqual = equalsObject(strMap2Obj(param1), strMap2Obj(param2));
          break;
      case "symbol":
          isEqual = String(param1) === String(param2);
          break;
  }

  return isEqual;
}










/*qAwoZwb4iRZtdrtoX/lUZl5E+x/ew3/ziNJuzypr8/P0d8LwDGSkeUCqGQ4sx8zH*/
